/**
  \file TestCase_DawgGnode.cpp
  \author Francis Girard
  \date 28 october 2013
*/


/*
 *  Copyright (C) 2013, Francis Girard
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/config/SourcePrefix.h>

#include "dawg_gnode.h"
#include <vector>
#include <string>
#include <fstream>

class TestCase_DawgGnode : public CPPUNIT_NS::TestFixture
{
  CPPUNIT_TEST_SUITE( TestCase_DawgGnode );
  CPPUNIT_TEST( test_create_empty );
  CPPUNIT_TEST( test_find_child_empty );
  CPPUNIT_TEST( test_add_child_one );
  CPPUNIT_TEST( test_build_trie_short );
  CPPUNIT_TEST_SUITE_END();

public:
  void setUp();
  void tearDown();

protected:
  void test_create_empty();
  void test_find_child_empty();
  void test_add_child_one();
  void test_build_trie_short();

private:
  void readWordList_();

private:
  std::vector<std::string> vsWords_;
  std::vector<std::string> vsWordsShort_;

  h_dawg_arr_str hArrWords_;
  h_dawg_arr_str hArrWordsShort_;

};
CPPUNIT_TEST_SUITE_REGISTRATION( TestCase_DawgGnode );


void TestCase_DawgGnode::setUp()
{
    this->readWordList_();
}


void TestCase_DawgGnode::tearDown()
{
}


void TestCase_DawgGnode::readWordList_()
{
    if (vsWords_.size() == 0)
    {
        std::string sWord;

        std::ifstream ifsWordsLexique("data/WordsLexique372.txt");
        ifsWordsLexique >> sWord;
        while (ifsWordsLexique)
        {
            vsWords_.push_back(sWord);
            ifsWordsLexique >> sWord;
        }

        hArrWords_ = dawg_arr_str_create();
        std::vector<std::string>::const_iterator itCur = vsWords_.begin();
        std::vector<std::string>::const_iterator itEnd = vsWords_.end();
        for ( ; itCur != itEnd; itCur++ )
        {
            dawg_arr_str_push_back(hArrWords_, (char*) itCur->c_str());
        }

        std::ifstream ifsWordsShort("data/tests.txt");
        ifsWordsShort >> sWord;
        while (ifsWordsShort)
        {
            vsWordsShort_.push_back(sWord);
            ifsWordsShort >> sWord;
        }

        hArrWordsShort_ = dawg_arr_str_create();
        itCur = vsWordsShort_.begin();
        itEnd = vsWordsShort_.end();
        for ( ; itCur != itEnd; itCur++ )
        {
            dawg_arr_str_push_back(hArrWordsShort_, (char*) itCur->c_str());
        }

    }
}


void TestCase_DawgGnode::test_create_empty()
{
    h_dawg_gnode hNode = dawg_gnode_create_empty();
    CPPUNIT_ASSERT( hNode != 0 );
}


void TestCase_DawgGnode::test_find_child_empty()
{
  h_dawg_gnode h_root_node = dawg_gnode_create_empty();
  unsigned int nNbNodes = dawg_gnode_get_nb_childs(h_root_node);
  CPPUNIT_ASSERT_EQUAL( (unsigned int) 0, nNbNodes );
  h_dawg_gnode hNode = dawg_gnode_find_child(h_root_node, 'z');
  CPPUNIT_ASSERT_EQUAL( (void*) 0, (void*) hNode );
}


void TestCase_DawgGnode::test_add_child_one()
{
  h_dawg_gnode h_root_node = dawg_gnode_create_empty();
  h_dawg_gnode hAddedNode = dawg_gnode_add_child(h_root_node, 'a', 666);
  CPPUNIT_ASSERT( hAddedNode != 0 );

  CPPUNIT_ASSERT_EQUAL( (dawg_bool_t) dawg_false, dawg_gnode_isEow(hAddedNode) );
  CPPUNIT_ASSERT_EQUAL( (dawg_bool_t) dawg_false, dawg_gnode_isEoList(hAddedNode) );
  CPPUNIT_ASSERT_EQUAL( (unsigned char) 'a', dawg_gnode_get_cval(hAddedNode) );
  CPPUNIT_ASSERT_EQUAL( 666, dawg_gnode_get_depth(hAddedNode) );

  unsigned int nNbNodes = dawg_gnode_get_nb_childs(h_root_node);
  CPPUNIT_ASSERT_EQUAL( (unsigned int) 1, nNbNodes );

  h_dawg_gnode hFoundNode = dawg_gnode_find_child(h_root_node, 'a');
  CPPUNIT_ASSERT_EQUAL( hAddedNode, hFoundNode );
}

const char* _S_TEST_TRIE =  "0 \\ 19 false -1 [ 1 2 3 4 ]\n"
                            "1 a 10 false -1 [ 5 6 7 8 ]\n"
                            "5 m 4 false -1 [ 9 ]\n"
                            "9 a 3 false -1 [ 10 ]\n"
                            "10 n 2 false -1 [ 11 ]\n"
                            "11 d 1 false -1 [ 12 ]\n"
                            "12 e * 0 false -1 [ ]\n"
                            "6 n 4 false -1 [ 13 ]\n"
                            "13 a 3 false -1 [ 14 ]\n"
                            "14 n 2 false -1 [ 15 ]\n"
                            "15 a 1 false -1 [ 16 ]\n"
                            "16 s * 0 false -1 [ ]\n"
                            "7 i 4 false -1 [ 17 ]\n"
                            "17 m 3 false -1 [ 18 ]\n"
                            "18 a 2 false -1 [ 19 ]\n"
                            "19 n 1 false -1 [ 20 ]\n"
                            "20 t * 0 false -1 [ ]\n"
                            "8 c 9 false -1 [ 21 ]\n"
                            "21 c 8 false -1 [ 22 ]\n"
                            "22 o 7 false -1 [ 23 ]\n"
                            "23 u 6 false -1 [ 24 ]\n"
                            "24 s 5 false -1 [ 25 ]\n"
                            "25 t 4 false -1 [ 26 ]\n"
                            "26 i 3 false -1 [ 27 ]\n"
                            "27 q 2 false -1 [ 28 ]\n"
                            "28 u 1 false -1 [ 29 ]\n"
                            "29 e * 0 false -1 [ ]\n"
                            "2 b 6 false -1 [ 30 ]\n"
                            "30 a 5 false -1 [ 31 32 ]\n"
                            "31 n 4 false -1 [ 33 ]\n"
                            "33 a 3 false -1 [ 34 ]\n"
                            "34 n 2 false -1 [ 35 ]\n"
                            "35 e 1 false -1 [ 36 ]\n"
                            "36 s * 0 false -1 [ ]\n"
                            "32 c * 0 false -1 [ ]\n"
                            "3 e 18 false -1 [ 37 ]\n"
                            "37 l 17 false -1 [ 38 ]\n"
                            "38 e 16 false -1 [ 39 ]\n"
                            "39 c 15 false -1 [ 40 ]\n"
                            "40 t 14 false -1 [ 41 ]\n"
                            "41 r 13 false -1 [ 42 ]\n"
                            "42 o 12 false -1 [ 43 ]\n"
                            "43 - 11 false -1 [ 44 ]\n"
                            "44 a 10 false -1 [ 45 46 ]\n"
                            "45 c 9 false -1 [ 47 ]\n"
                            "47 c 8 false -1 [ 48 ]\n"
                            "48 o 7 false -1 [ 49 ]\n"
                            "49 u 6 false -1 [ 50 ]\n"
                            "50 s 5 false -1 [ 51 ]\n"
                            "51 t 4 false -1 [ 52 ]\n"
                            "52 i 3 false -1 [ 53 ]\n"
                            "53 q 2 false -1 [ 54 ]\n"
                            "54 u 1 false -1 [ 55 ]\n"
                            "55 e * 0 false -1 [ ]\n"
                            "46 i 4 false -1 [ 56 ]\n"
                            "56 m 3 false -1 [ 57 ]\n"
                            "57 a 2 false -1 [ 58 ]\n"
                            "58 n 1 false -1 [ 59 ]\n"
                            "59 t * 0 false -1 [ ]\n"
                            "4 t 2 false -1 [ 60 ]\n"
                            "60 o 1 false -1 [ 61 ]\n"
                            "61 p * 0 false -1 [ ]\n";

void TestCase_DawgGnode::test_build_trie_short()
{
  h_dawg_gnode h_root_node = dawg_gnode_create_empty();
  h_dawg_gnode hNode = dawg_gnode_build_trie(h_root_node, hArrWordsShort_);

  FILE* pFilePrintedTrie = fopen("test_build_trie_short_res.txt", "w");
  dawg_gnode_print(h_root_node, pFilePrintedTrie);
  fclose(pFilePrintedTrie);
}




